package com.bedpotato.socket.echo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class EchoServer {
	private int port = 10000;
	private ServerSocket serverSocket;
	private ExecutorService executor;// 线程池
	private final int pool_size = 4;

	private int portForShutdown = 10001;
	private ServerSocket serverSocketForShutdown = null;
	private boolean isShutdown = false;

	private Thread shutdownThread = new Thread() // 负责关闭服务器的线程
	{
		public void start() {
			this.setDaemon(true); // 设为守护线程
			super.start();
		}

		public void run() {
			while (!isShutdown) {
				Socket socketForShutdown = null;
				try {
					socketForShutdown = serverSocketForShutdown.accept();
					BufferedReader br = new BufferedReader(
							new InputStreamReader(
									socketForShutdown.getInputStream()));
					String command = br.readLine();
					if (command.equals("shutdown")) {
						long beginTime = System.currentTimeMillis();
						socketForShutdown.getOutputStream().write(
								"服务器正在关闭\r\n".getBytes());
						isShutdown = true;
						executor.shutdown();
						while (!executor.isTerminated()) {
							executor.awaitTermination(30, TimeUnit.SECONDS);
						}
						serverSocket.close();
						long endTime = System.currentTimeMillis();
						socketForShutdown
								.getOutputStream()
								.write(("服务器已经关闭,耗时" + (beginTime - endTime) + "毫秒\r\n")
										.getBytes());
						socketForShutdown.close();
					} else {
						socketForShutdown.getOutputStream().write(
								"错误的命令\r\n".getBytes());
						// socketForShutdown.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	};

	public EchoServer() throws IOException {
		serverSocket = new ServerSocket(port);
		serverSocket.setSoTimeout(60000);
		serverSocketForShutdown = new ServerSocket(portForShutdown);
		shutdownThread.start();
		System.out.println("server started...");
	}

	public void service() {
		while (!isShutdown) {
			Socket socket = null;
			try {
				socket = serverSocket.accept();
				executor = Executors.newFixedThreadPool(Runtime.getRuntime()
						.availableProcessors() * pool_size);
				executor.execute(new Handler(socket));
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

	public static void main(String args[]) {
		try {
			new EchoServer().service();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}